package com.hu.system.converter;

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.hu.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.text.DecimalFormat;

/**
 * 容错Integer转换器
 * 参考原ExcelUtil的转换逻辑
 * <p>
 * 转换规则（与原ExcelUtil保持一致）：
 * 1. 数字类型：转为字符串后去除小数点，再转Integer
 * 2. 字符串类型：检查是否为数字，是则转换，否则返回null
 * 3. 空值：返回null
 * 4. 异常情况：返回null（不抛异常）
 *
 * @author hu-erp
 */
public class TolerantIntegerConverter implements Converter<Integer> {

    private static final Logger log = LoggerFactory.getLogger(TolerantIntegerConverter.class);

    @Override
    public Class<Integer> supportJavaTypeKey() {
        return Integer.class;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return null; // 支持所有Excel类型
    }

    /**
     * 读取Excel时的转换
     * 参考ExcelUtil.getCellValue + 字段转换逻辑
     */
    @Override
    public Integer convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty,
                                     GlobalConfiguration globalConfiguration) {
        if (cellData == null) {
            return null;
        }

        try {
            Object val = "";

            // 第一步：根据单元格类型获取值（模拟getCellValue）
            switch (cellData.getType()) {
                case NUMBER:
                    // 数字类型
                    BigDecimal numberValue = cellData.getNumberValue();
                    if (numberValue != null) {
                        // 如果是整数，转为字符串（去掉.0）
                        if (numberValue.remainder(BigDecimal.ONE).compareTo(BigDecimal.ZERO) == 0) {
                            val = new DecimalFormat("0").format(numberValue);
                        } else {
                            val = numberValue.toString();
                        }
                    }
                    break;

                case STRING:
                    // 字符串类型
                    String stringValue = cellData.getStringValue();
                    if (stringValue != null) {
                        val = stringValue.trim();
                    }
                    break;

                case BOOLEAN:
                    // 布尔类型：true=1, false=0
                    return cellData.getBooleanValue() ? 1 : 0;

                case ERROR:
                case EMPTY:
                default:
                    return null;
            }

            // 第二步：字段类型转换（模拟ExcelUtil的字段赋值逻辑）
            String strVal = StringUtils.isNull(val) ? "" : val.toString().trim();

            // 空值返回null
            if (strVal.isEmpty()) {
                return null;
            }

            // 检查是否为数字（isNumeric检查）
            if (StringUtils.isNumeric(strVal)) {
                // 转换为Integer
                try {
                    return Integer.valueOf(strVal);
                } catch (NumberFormatException e) {
                    // 可能数字太大，尝试先转Long再转Int
                    try {
                        return Long.valueOf(strVal).intValue();
                    } catch (Exception ex) {
                        log.warn("数字 '{}' 超出Integer范围，返回null", strVal);
                        return null;
                    }
                }
            } else {
                // 非数字字符串，返回null（与原ExcelUtil行为一致）
                log.debug("非数字字符串 '{}'，返回null", strVal);
                return null;
            }

        } catch (Exception e) {
            // 异常情况返回null（与原ExcelUtil行为一致）
            log.warn("转换Integer失败，返回null", e);
            return null;
        }
    }

    /**
     * 写入Excel时的转换
     */
    @Override
    public WriteCellData<?> convertToExcelData(Integer value, ExcelContentProperty contentProperty,
                                                GlobalConfiguration globalConfiguration) {
        if (value == null) {
            return new WriteCellData<>("");
        }
        // 转为String以确保兼容性
        return new WriteCellData<>(String.valueOf(value));
    }
}

